package com.qingcloud.adminbackend.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qingcloud.adminbackend.constant.WamingConstant;
import com.qingcloud.adminbackend.base.AjaxResult;
import com.qingcloud.adminbackend.entity.aline.*;
import com.qingcloud.adminbackend.entity.mqtt.detail.*;
import com.qingcloud.adminbackend.mapper.*;
import com.qingcloud.adminbackend.entity.aline.*;
import com.qingcloud.adminbackend.entity.command.CommandRecord;
import com.qingcloud.adminbackend.entity.config.SysCommonConfig;
import com.qingcloud.adminbackend.entity.config.SysSensorFactorConfig;
import com.qingcloud.adminbackend.entity.equipment.ModelDTO;
import com.qingcloud.adminbackend.entity.mqtt.AuthKey;
import com.qingcloud.adminbackend.entity.mqtt.ParamObj;
import com.qingcloud.adminbackend.entity.mqtt.detail.*;
import com.qingcloud.adminbackend.enums.BaseCommandEnum;
import com.qingcloud.adminbackend.mapper.*;
import com.qingcloud.adminbackend.service.ISysSensorAlineAitectServiceNew;
import com.qingcloud.adminbackend.utils.ExcelUtil;
import com.qingcloud.adminbackend.utils.OKHttpUtil;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 传感器数据校准表(室内设备) 服务实现类
 * </p>
 *
 * @author liuziyong
 * @since 2019-04-11
 */
@Service
public class SysSensorAlineAitectServiceNewImpl extends ServiceImpl<SysSensorAlineAitectMapper, SysSensorAlineAitect> implements ISysSensorAlineAitectServiceNew {

    private static Logger logger = LoggerFactory.getLogger(SysSensorAlineAitectServiceNewImpl.class);

    private static final String MQTT_COMMON_CONFIG_KEY = "qingcloudiot_command_url";//室内设备参数下发url地址
    private static final String GRID_COMMON_CONFIG_KEY = "station_command_url";//室内设备参数下发url地址

    private static final String COMMAND_SHORT_TIPS = "指令已下发";
    private static final String COMMAND_LONG_TIPS = "指令已下发，稍后到设备详情页查看结果";
    private static final String COMMAND_FAIL_TIPS = "下发失败";

    /*
    MQTT命令
     */
    private static final String RESET_COMMAND = "/command/mqtt/command/reset";// 复位
    private static final String SET_KB_COMMAND = "/command/mqtt/command/setKBCommand";//下发KB值指令
    private static final String SET_WORK_MODE = "/command/mqtt/command/setWorkMode";// 设置工作模式
    private static final String SET_LED_STATUS = "/command/mqtt/command/setLedStatus";// 设置led状态
    private static final String SET_LED_LIGHT = "/command/mqtt/command/setLedLight";// 设置led亮度
    private static final String SET_MQTT_COMMAND = "/command/mqtt/command/setMqttTopic";// MQTT登录信息及Topic修改
    private static final String SET_REPORT_TIME = "/command/mqtt/command/setReportTime";// 设置上传时间间隔
    private static final String SET_IP_PORT = "/command/mqtt/command/setIpPort";// 设置IP端口

    private static final String QUERY_IP_PORT = "/command/mqtt/command/queryIpPort";// 查询IP
    private static final String QUERY_REPORT_TIME = "/command/mqtt/command/queryReportTime";// 查询上传时间
    private static final String QUERY_KB_COMMAND = "/command/mqtt/command/queryKBCommand";//查询KB值指令
    private static final String QUERY_WORK_MODE = "/command/mqtt/command/queryWorkMode";// 查询工作模式
    private static final String QUERY_LED_STATUS = "/command/mqtt/command/queryLedStatus";// 查询led状态
    private static final String QUERY_LED_LIGHT = "/command/mqtt/command/queryLedLight";// 查询led亮度
    private static final String QUERY_SENSORS_STATUS = "/command/mqtt/command/querySensorsStatus";// 查询传感器状态
    private static final String QUERY_DEVICE_INFO = "/command/mqtt/command/queryDeviceInfo";// 查询设备详情

    @Resource
    private SysSensorAlineAitectMapper sysSensorAlineAitectMapper;

    @Resource
    private SysSensorFactorConfigMapper sysSensorFactorConfigMapper;

    @Resource
    private SysCommonConfigMapper sysCommonConfigMapper;

    @Resource
    private SysEquipmentMapper sysEquipmentMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private BaseServiceImpl baseService;


    @Override
    public IPage<AlinePageAitectVO> findPage(AlinePageDTO alinePageDTO) {

        //获取所属权限的设备信息
        List<ModelDTO> modelDTOList = baseService.getEquipmentIds(alinePageDTO.getUserId(),
                alinePageDTO.getOrderIdList(), alinePageDTO.getOrgList(), alinePageDTO.getEquipmentPool());

        //设备列表List
        List<String> equipmentIdList = modelDTOList.stream().map(ModelDTO::getModelId).collect(Collectors.toList());

        if (CollectionUtil.isEmpty(equipmentIdList)) {
            Page<AlinePageAitectVO> page = new Page<>(alinePageDTO.getCurrentPage(), alinePageDTO.getPerPage());
            page.setRecords(null);
            page.setTotal(0);
            return page;
        }

        //设备Map封装
        Map<String, ModelDTO> modelDTOMap = modelDTOList.stream().collect(Collectors.toMap(ModelDTO::getModelId, modelDTO -> modelDTO));

        //设备分页查询
        alinePageDTO.setEquipmentIdList(equipmentIdList);
        List<AlinePageAitectVO> alinePageVOList = sysSensorAlineAitectMapper.findPage(alinePageDTO);

        //设备权限处理
        alinePageVOList.stream().forEach(alinePageAitectVO -> {
            alinePageAitectVO.setManageAuth(modelDTOMap.get(alinePageAitectVO.getEquipmentId()).getManageAuth());
            alinePageAitectVO.setReadAuth(modelDTOMap.get(alinePageAitectVO.getEquipmentId()).getReadAuth());
        });

        Long count = sysSensorAlineAitectMapper.countSensorAline(alinePageDTO);
        Page<AlinePageAitectVO> page = new Page<>(alinePageDTO.getCurrentPage(), alinePageDTO.getPerPage());
        page.setRecords(alinePageVOList);
        page.setTotal(count);
        return page;
    }

    @Override
    public List<AlinePageAitectVO> find(AlinePageDTO alinePageDTO) {
        alinePageDTO.setPerPage(null);
        alinePageDTO.setCurrentPage(null);
        //获取所属权限的设备信息
        List<ModelDTO> modelDTOList = baseService.getEquipmentIds(alinePageDTO.getUserId(),
                alinePageDTO.getOrderIdList(), alinePageDTO.getOrgList(), alinePageDTO.getEquipmentPool());
        //设备列表List
        List<String> equipmentIdList = modelDTOList.stream().map(ModelDTO::getModelId).collect(Collectors.toList());

        if (CollectionUtil.isEmpty(equipmentIdList)) {
            return null;
        }

        alinePageDTO.setEquipmentIdList(equipmentIdList);
        return sysSensorAlineAitectMapper.findPage(alinePageDTO);
    }

    @Override
    public AjaxResult setCommand(BaseSetCommandDTO baseSetCommandDTO) {
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        Integer commandCode = baseSetCommandDTO.getCommandCode();
        if (commandCode == null) {
            return new AjaxResult(WamingConstant.FAILURE, "命令不能为空", null);
        }
        if (baseSetCommandDTO.getEquipmentIds() == null) {
            return new AjaxResult(WamingConstant.FAILURE, "设备不能为空", null);
        }
        if (commandCode.equals(BaseCommandEnum.RESET.getCode())) {
            String url = sysCommonConfig.getValue() + RESET_COMMAND;
            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }
        if (commandCode.equals(BaseCommandEnum.SETWORKMODE.getCode())) {
            String url = sysCommonConfig.getValue() + SET_WORK_MODE;
            WorkMode mode = new WorkMode();
            mode.setWorkMode((Integer) baseSetCommandDTO.getParams());
            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }
        if (commandCode.equals(BaseCommandEnum.SETLEDSTATUS.getCode())) {
            String url = sysCommonConfig.getValue() + SET_LED_STATUS;
            LedStatus mode = new LedStatus();
            mode.setLedStatus((Integer) baseSetCommandDTO.getParams());
            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }
        if (commandCode.equals(BaseCommandEnum.SETLEDLIGHT.getCode())) {
            String url = sysCommonConfig.getValue() + SET_LED_LIGHT;
            LedLight mode = new LedLight();
            mode.setLedLight((Integer) baseSetCommandDTO.getParams());
            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }
        if (commandCode.equals(BaseCommandEnum.QUERYREPORTTIME.getCode())) {
            String url = sysCommonConfig.getValue() + SET_REPORT_TIME;
            ReportTime mode = new ReportTime();
            if(baseSetCommandDTO.getParams() instanceof String){
                mode.setDataReport(Integer.parseInt((String)baseSetCommandDTO.getParams()));
            }else{
                mode.setDataReport((Integer)baseSetCommandDTO.getParams() );
            }
            mode.setLpReport(600);
            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }

        if (commandCode.equals(BaseCommandEnum.IPPORT.getCode())) {
            String url = sysCommonConfig.getValue() + SET_IP_PORT;

            logger.debug("ipport params: {}",baseSetCommandDTO.getParams());
            JSONObject jsonObject = (JSONObject)baseSetCommandDTO.getParams();
            String json = jsonObject.toJSONString();
            IpPort mode = JSONObject.parseObject(jsonObject.toJSONString(),IpPort.class);

            AjaxResult ajaxResult = sendSetRequest(baseSetCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }

        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_LONG_TIPS, null);
    }

    private AjaxResult sendSetRequest(List<String> equipmentList, String url, Object param) {
        for (String equipmentId : equipmentList) {
            AuthKey authKey = new AuthKey(equipmentId);
            try {
                String jsonString;
                if (param != null) {
                    ParamObj obj = new ParamObj<>();
                    obj.setAuthKey(authKey);
                    obj.setObj(param);
                    jsonString = JSONObject.toJSONString(obj);
                } else {
                    jsonString = JSONObject.toJSONString(authKey);
                }
                String resultStr = OKHttpUtil.httpPost(url, jsonString);
                logger.info("参数指令下发 result, {}", resultStr);
                AjaxResult ajaxResult = JSONObject.parseObject(resultStr, AjaxResult.class);
                if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                    return ajaxResult;
                }
            } catch (Exception e) {
                logger.error("参数指令下发 error, {}", e);
                return new AjaxResult(WamingConstant.FAILURE, COMMAND_FAIL_TIPS, null);
            }
        }
        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_LONG_TIPS, null);
    }

    @Override
    public AjaxResult setMqttCommand(MqttSetCommandDTO mqttSetCommandDTO) {
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        String url = sysCommonConfig.getValue() + SET_MQTT_COMMAND;
        MqttTopic mode = new MqttTopic();
        // todo ip和port还没支持
        mode.setClientId(mqttSetCommandDTO.getClientId());
        mode.setUserName(mqttSetCommandDTO.getUserName());
        mode.setPassword(mqttSetCommandDTO.getPassword());
        mode.setDevInfo(mqttSetCommandDTO.getTopic().getDevInfo());
        mode.setDataPost(mqttSetCommandDTO.getTopic().getDataPost());
        mode.setProPost(mqttSetCommandDTO.getTopic().getProPost());
        mode.setProSet(mqttSetCommandDTO.getTopic().getProSet());
        mode.setEventPost(mqttSetCommandDTO.getTopic().getEventPost());
        mode.setOtaUpgrade(mqttSetCommandDTO.getTopic().getOtaUpgrade());
        mode.setOtaProgress(mqttSetCommandDTO.getTopic().getOtaProgress());
        mode.setOtaVersion(mqttSetCommandDTO.getTopic().getOtaVersion());
        AjaxResult ajaxResult = sendSetRequest(mqttSetCommandDTO.getEquipmentIds(), url, mode);
        if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
            return ajaxResult;
        }
        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_LONG_TIPS, null);
    }

    @Override
    public AjaxResult setKb(List<AitectKbDTO> aitectKbDTOList) {
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        String url = sysCommonConfig.getValue() + SET_KB_COMMAND;
        List<SysSensorFactorConfig> sysSensorFactorConfigList = sysSensorFactorConfigMapper.findAitech();
        Map<Integer, Integer> factorIdMap = sysSensorFactorConfigList.stream().collect(
                Collectors.toMap(SysSensorFactorConfig::getFactorId, SysSensorFactorConfig::getAitechCode));

        for (AitectKbDTO aitectKbDTO : aitectKbDTOList) {
            if (Objects.isNull(aitectKbDTO.getFactorCode())) {
                aitectKbDTO.setFactorCode(factorIdMap.get(aitectKbDTO.getFactorId()));
            }
            ParamObj<KbCommandDto> obj = new ParamObj<>();
            AuthKey authKey = new AuthKey(aitectKbDTO.getEquipmentId());
            KbCommandDto mode = new KbCommandDto();
            KbRange kbRange = new KbRange();
            kbRange.setStart(aitectKbDTO.getStartValue());
            kbRange.setEnd(aitectKbDTO.getEndValue());
            kbRange.setK(aitectKbDTO.getParamK());
            kbRange.setB(aitectKbDTO.getParamB());
            mode.setFactorCode(aitectKbDTO.getFactorCode());
            mode.setKbRanges(Collections.singletonList(kbRange));
            obj.setAuthKey(authKey);
            obj.setObj(mode);
            try {
                String paramJson = JSON.toJSONString(obj);
                logger.info("KB值下发参数：" + paramJson);
                String resultStr = OKHttpUtil.httpPost(url, paramJson);
                logger.info("KB值下发设置返回结果:" + resultStr);
                AjaxResult ajaxResult = JSONObject.parseObject(resultStr, AjaxResult.class);
                if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                    return ajaxResult;
                }
            } catch (Exception e) {
                logger.error("KB值设置下发 error, {}", e);
                return new AjaxResult(WamingConstant.FAILURE, COMMAND_FAIL_TIPS, null);
            }
        }
        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_SHORT_TIPS, null);
    }

    @Override
    public AjaxResult queryCommand(BaseQueryCommandDTO baseQueryCommandDTO) {
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        Integer commandCode = baseQueryCommandDTO.getCommandCode();
        if (commandCode == null) {
            return new AjaxResult(WamingConstant.FAILURE, "命令不能为空", null);
        }
        if (baseQueryCommandDTO.getEquipmentIds() == null) {
            return new AjaxResult(WamingConstant.FAILURE, "设备不能为空", null);
        }
        if (commandCode.equals(BaseCommandEnum.KBCOMMANDCODE.getCode())) {
            //获取室内新业务设备指令下发码
            List<Integer> factorIdList = (List<Integer>) baseQueryCommandDTO.getParams();
            List<SysSensorFactorConfig> sysSensorFactorConfigList = sysSensorFactorConfigMapper.findByFactorId(factorIdList);
            List<Integer> factorCodeList = sysSensorFactorConfigList.stream().filter(it -> it.getAitechCode() != null)
                    .map(SysSensorFactorConfig::getAitechCode).collect(Collectors.toList());
            //KB值查询
            KbQueryDto mode = new KbQueryDto();
            mode.setSensorTypes(factorCodeList);
            String url = sysCommonConfig.getValue() + QUERY_KB_COMMAND;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, mode);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.QUERYREPORTTIME.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_REPORT_TIME;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.SETWORKMODE.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_WORK_MODE;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.SETLEDSTATUS.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_LED_STATUS;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.SETLEDLIGHT.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_LED_LIGHT;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.QUERYSENSORSSTATUS.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_SENSORS_STATUS;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        } else if (commandCode.equals(BaseCommandEnum.QUERYDEVICEINFO.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_DEVICE_INFO;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }else if (commandCode.equals(BaseCommandEnum.IPPORT.getCode())) {
            String url = sysCommonConfig.getValue() + QUERY_IP_PORT;
            AjaxResult ajaxResult = sendSetRequest(baseQueryCommandDTO.getEquipmentIds(), url, null);
            if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
                return ajaxResult;
            }
        }
        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_LONG_TIPS, null);
    }

    @Override
    public AjaxResult command(CommandAdapter adapter) {
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        String url = adapter.getUrl(sysCommonConfig.getValue());
        try {
            String paramJson = adapter.toReceiveJson();
            //基础指令查询下发
            logger.info("指令地址：" + url);
            logger.info("指令参数：" + paramJson);
            String resultStr = OKHttpUtil.httpPost(url, paramJson);
            logger.info("指令查询结果:" + resultStr);
            return handlerCmdResult(resultStr);
        } catch (Exception e) {
            logger.error("指令查询下发 error, {}", e);
            return new AjaxResult(WamingConstant.FAILURE, COMMAND_FAIL_TIPS, null);
        }
    }

    private AjaxResult handlerCmdResult(String resultStr) {
        final AjaxResult<CommandRecord> tcpResultDto = JSON.parseObject(resultStr, AjaxResult.class);
        if (tcpResultDto != null && tcpResultDto.getErroCode() != 0) {
            if (WamingConstant.SUCCESS == tcpResultDto.getErroCode()) {
                tcpResultDto.setErroMsg(COMMAND_SHORT_TIPS);
            }
            return tcpResultDto;
        } else
            return new AjaxResult(WamingConstant.FAILURE, COMMAND_FAIL_TIPS, null);
    }

    @Override
    public AjaxResult importQueryKb(MultipartFile excelFile, String userId, Boolean isAdmin) throws Exception {
        InputStream inputStream = excelFile.getInputStream();
        List<String> equipmentIdList = new ArrayList<>();
        //解析模板获取设备编号列表
        AjaxResult ajaxResult = paseEquipmentIds(inputStream, userId, isAdmin, equipmentIdList);
        if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
            return ajaxResult;
        }
        SysCommonConfig sysCommonConfig = sysCommonConfigMapper.findByKey(GRID_COMMON_CONFIG_KEY);
        String url = sysCommonConfig.getValue() + QUERY_KB_COMMAND;

        //获取室内新业务监测因子下发码
        List<SysSensorFactorConfig> sysSensorFactorConfigList = sysSensorFactorConfigMapper.findAitech();
        List<Integer> factorCodeList = sysSensorFactorConfigList.stream().map(
                SysSensorFactorConfig::getAitechCode).collect(Collectors.toList());
        //KB值查询
        KbQueryDto mode = new KbQueryDto();
        mode.setSensorTypes(factorCodeList);
        ajaxResult = sendSetRequest(equipmentIdList, url, mode);
        if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
            return ajaxResult;
        }
        return new AjaxResult(WamingConstant.SUCCESS, COMMAND_SHORT_TIPS, null);
    }

    @Override
    public AjaxResult importSetKb(MultipartFile excelFile, String userId, Boolean isAdmin) {

        List<AitectKbDTO> aitectKbDTOList = new ArrayList<>();
        //解析KB值设置指令下发模板
        AjaxResult ajaxResult = paseAitectKbDTO(excelFile, aitectKbDTOList, userId, isAdmin);
        if (!WamingConstant.SUCCESS.equals(ajaxResult.getErroCode())) {
            return ajaxResult;
        }
        return setKb(aitectKbDTOList);
    }

    /**
     * 模板导入解析设备编号
     */
    private AjaxResult paseEquipmentIds(InputStream input, String userId, Boolean isAdmin, List<String> equipmentIdList) {
        //获取室内设备列表
        List<String> aitechEquipmentIds = sysEquipmentMapper.findAitechEquipmentIds();

        //获取所属权限的设备信息
        List<ModelDTO> modelDTOList = baseService.getEquipmentIds(userId, null, null, 0);
        List<String> manageEquipmentIdList = modelDTOList.stream().filter(
                modelDTO -> modelDTO.getManageAuth() == 1)
                .map(ModelDTO::getModelId).collect(Collectors.toList());

        try {
            Workbook workbook = new XSSFWorkbook(input);
            Sheet sheet = workbook.getSheetAt(0);
            for (int rowNum = 1; rowNum <= sheet.getPhysicalNumberOfRows(); rowNum++) {
                Row row = sheet.getRow(rowNum);
                if (row == null) {
                    continue;
                }
                String equipmentId = ExcelUtil.getCellValue(row.getCell(0));
                if (StrUtil.isNotBlank(equipmentId) && !"".equals(equipmentId.replace(".0000", "").trim())) {
                    equipmentId = equipmentId.replace(".0000", "").trim();
                    if (equipmentIdList.contains(equipmentId)) {
                        logger.error("第" + rowNum + "行设备编号重复");
                        return new AjaxResult(WamingConstant.FAILURE, "第" + rowNum + "行设备编号重复");
                    } else if (!aitechEquipmentIds.contains(equipmentId)) {
                        logger.error("第" + rowNum + "行设备" + equipmentId + "非室内MQTT设备");
                        return new AjaxResult(WamingConstant.FAILURE,
                                "第" + rowNum + "行设备" + equipmentId + "非室内MQTT设备");
                    } else if (!manageEquipmentIdList.contains(equipmentId)) {
                        logger.error("第" + rowNum + "行设备" + equipmentId + "无操作权限");
                        return new AjaxResult(WamingConstant.FAILURE,
                                "第" + rowNum + "行设备" + equipmentId + "无操作权限");
                    } else {
                        equipmentIdList.add(equipmentId);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return new AjaxResult(WamingConstant.FAILURE, "模板解析错误", null);
        }
        if (equipmentIdList.isEmpty()) {
            return new AjaxResult(WamingConstant.FAILURE, "设备编号不能为空", null);
        }
        return new AjaxResult(WamingConstant.SUCCESS, null, null);
    }


    /**
     * KB值设置指令下发模板解析
     */
    private AjaxResult paseAitectKbDTO(MultipartFile excelFile,
                                       List<AitectKbDTO> aitectKbDTOList,
                                       String userId,
                                       Boolean isAdmin) {
        AjaxResult result = new AjaxResult();
        //获取室内设备列表
        List<String> aitechEquipmentIds = sysEquipmentMapper.findAitechEquipmentIds();

        //获取所属权限的设备信息
        List<ModelDTO> modelDTOList = baseService.getEquipmentIds(userId, null, null, 0);
        List<String> manageEquipmentIdList = modelDTOList.stream().filter(
                modelDTO -> modelDTO.getManageAuth() == 1)
                .map(ModelDTO::getModelId).collect(Collectors.toList());

        Map<String, List<Map<String, BigDecimal>>> equipmentDataMap = new HashMap<>();
        try {
            // 加载文件流
            if (FileMagic.valueOf(excelFile.getInputStream()) == FileMagic.OOXML) {
                XSSFWorkbook workbook2007 = new XSSFWorkbook(new BufferedInputStream(excelFile.getInputStream()));
                // 取得第一个sheet
                XSSFSheet sheet = workbook2007.getSheetAt(0);
                // 多少行
                int count = sheet.getLastRowNum();
                logger.info("批量导入KB值下发个数：" + count);
                XSSFCell cell;
                if (count < 1) {
                    result.setErroMsg("请输入设备编号");
                    result.setErroCode(WamingConstant.FAILURE);
                    return result;
                }
                for (int i = 1; i <= count; i++) {
                    AitectKbDTO aitectKbDTO = new AitectKbDTO();
                    String equipmentId = null;
                    Integer factorCode = null;
                    BigDecimal startValue = null;
                    BigDecimal endValue = null;
                    BigDecimal paramK = null;
                    BigDecimal paramB = null;

                    // 获取行对象
                    XSSFRow row = sheet.getRow(i);
                    if (row == null) {// 如果为空，不处理
                        continue;
                    }
                    // 设备编号
                    cell = row.getCell(0);
                    if (cell == null) {
                        logger.error("第" + i + "行设备编号为空");
                        result.setErroMsg("第" + i + "行设备编号为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    } else {
                        equipmentId = ExcelUtil.getCellStringValue(cell);
                        // 合法检验
                        if (StrUtil.isNotBlank(equipmentId)) {
                            if (!aitechEquipmentIds.contains(equipmentId)) {
                                logger.error("第" + i + "行设备" + equipmentId + "非室内MQTT设备");
                                result.setErroMsg("第" + i + "行设备" + equipmentId + "非室内MQTT设备");
                                result.setErroCode(WamingConstant.FAILURE);
                                return result;
                            }
                            if (!manageEquipmentIdList.contains(equipmentId)) {
                                logger.error("第" + i + "行设备编号" + equipmentId + "无操作权限");
                                result.setErroMsg("第" + i + "行设备编号" + equipmentId + "无操作权限");
                                result.setErroCode(WamingConstant.FAILURE);
                                return result;
                            }
                            aitectKbDTO.setEquipmentId(equipmentId);
                        } else {
                            logger.error("第" + i + "行设备编号输入有误：");
                            result.setErroMsg("第" + i + "行设备编号输入有误：");
                            result.setErroCode(WamingConstant.FAILURE);
                            return result;
                        }
                    }

                    // 监测因子
                    cell = row.getCell(1);
                    if (cell == null) {
                        logger.error("第" + i + "行监测因子为空");
                        result.setErroMsg("第" + i + "行监测因子为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    } else {
                        String factorName = ExcelUtil.getCellStringValue(cell);
                        if (StrUtil.isNotBlank(factorName)) {
                            switch (factorName.toUpperCase()) {
                                case "PM25":
                                    factorCode = 1;
                                    break;
                                case "PM10":
                                    factorCode = 2;
                                    break;
                                case "CO2":
                                    factorCode = 3;
                                    break;
                                case "甲醛":
                                    factorCode = 4;
                                    break;
                                case "TVOC":
                                    factorCode = 5;
                                    break;
                                case "温度":
                                    factorCode = 6;
                                    break;
                                case "湿度":
                                    factorCode = 7;
                                    break;
                                default:
                            }
                        }
                        if (factorCode == null) {
                            logger.error("第" + i + "行监测因子输入有误");
                            result.setErroMsg("第" + i + "行监测因子输入有误");
                            result.setErroCode(WamingConstant.FAILURE);
                            return result;
                        }
                        aitectKbDTO.setFactorCode(factorCode);
                    }


                    // 最小浓度区间值
                    cell = row.getCell(2);
                    if (cell != null) {
                        String strStartValue = ExcelUtil.getCellStringValue(cell);
                        if (StrUtil.isNotBlank(strStartValue)) {
                            startValue = new BigDecimal(strStartValue).setScale(6, BigDecimal.ROUND_HALF_UP);
                            aitectKbDTO.setStartValue(startValue);
                        }
                    }
                    if (startValue == null) {
                        logger.error("第" + i + "行最小浓度区间值为空");
                        result.setErroMsg("第" + i + "行最小浓度区间值为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    // 最大浓度区间值
                    cell = row.getCell(3);
                    if (cell != null) {
                        String strEndValue = ExcelUtil.getCellStringValue(cell);
                        if (StrUtil.isNotBlank(strEndValue)) {
                            endValue = new BigDecimal(strEndValue).setScale(6, BigDecimal.ROUND_HALF_UP);
                            aitectKbDTO.setEndValue(endValue);
                        }
                    }
                    if (endValue == null) {
                        logger.error("第" + i + "行最大浓度区间值为空");
                        result.setErroMsg("第" + i + "行最大浓度区间值为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    //最小值必须小于最大值
                    if (startValue.compareTo(endValue) == 0
                            || startValue.compareTo(endValue) == 1) {
                        logger.error("第" + i + "行浓度区间输入有误");
                        result.setErroMsg("第" + i + "行浓度区间值输入有误");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    // K值
                    cell = row.getCell(4);
                    if (cell != null) {
                        String strParamK = ExcelUtil.getCellStringValue(cell);
                        if (StrUtil.isNotBlank(strParamK)) {
                            paramK = new BigDecimal(strParamK).setScale(6, BigDecimal.ROUND_HALF_UP);
                            aitectKbDTO.setParamK(paramK);
                        }
                    }
                    if (paramK == null) {
                        logger.error("第" + i + "行K值输入为空");
                        result.setErroMsg("第" + i + "行K值输入为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    // B值
                    cell = row.getCell(5);
                    if (cell != null) {
                        String strParamB = ExcelUtil.getCellStringValue(cell);
                        if (StrUtil.isNotBlank(strParamB)) {
                            paramB = new BigDecimal(strParamB).setScale(6, BigDecimal.ROUND_HALF_UP);
                            aitectKbDTO.setParamB(paramB);
                        }
                    }

                    if (paramB == null) {
                        logger.error("第" + i + "行B值输入为空");
                        result.setErroMsg("第" + i + "行B值输入为空");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    String key = equipmentId + "&" + factorCode;
                    List<Map<String, BigDecimal>> mapList = equipmentDataMap.get(key);

                    //污染浓度最多限制6个
                    if (mapList != null && mapList.size() >= 6) {
                        logger.error("第" + i + "行设备编号" + equipmentId + "浓度区间不能超过6个");
                        result.setErroMsg("第" + i + "行设备编号" + equipmentId + "浓度区间不能超过6个");
                        result.setErroCode(WamingConstant.FAILURE);
                        return result;
                    }

                    if (mapList == null) {
                        mapList = new ArrayList<>();
                    }

                    //污染浓度区间限制重复区间
                    for (Map<String, BigDecimal> map : mapList) {
                        BigDecimal startValueTmp = map.get("startValue");
                        BigDecimal endValueTmp = map.get("endValue");
                        BigDecimal maxStartValue = startValue.compareTo(startValueTmp) == -1 ? startValueTmp : startValue;
                        BigDecimal minEndValue = endValue.compareTo(endValueTmp) == -1 ? endValue : endValueTmp;
                        if (maxStartValue.compareTo(minEndValue) == -1 || maxStartValue.compareTo(minEndValue) == 0) {
                            logger.error("第" + i + "行浓度区间范围重复");
                            result.setErroMsg("第" + i + "行浓度区间范围重复");
                            result.setErroCode(WamingConstant.FAILURE);
                            return result;
                        }
                    }
                    Map<String, BigDecimal> map = new HashMap<>();
                    map.put("startValue", startValue);
                    map.put("endValue", endValue);
                    mapList.add(map);
                    equipmentDataMap.put(key, mapList);
                    aitectKbDTOList.add(aitectKbDTO);
                }
            }
        } catch (Exception e) {
            result.setErroMsg("模板解析异常");
            result.setErroCode(WamingConstant.FAILURE);
            return result;
        }
        result.setErroCode(WamingConstant.SUCCESS);
        return result;
    }

}
